#include "Driver_LPTIM32.h"

static void Driver_LPTIM32_SetDutyCycle(uint32_t channel, uint8_t dutyCycle);

static GPIOConfig lptimGPIOConfigList[] = {
    [LPTIM32_GPIO_INDEX_AM9]  = { GPIOA,
                                  { FL_GPIO_PIN_8, FL_GPIO_MODE_DIGITAL, FL_GPIO_OUTPUT_PUSHPULL, FL_DISABLE,
                                    FL_ENABLE, FL_DISABLE } },
    [LPTIM32_GPIO_INDEX_AM10] = { GPIOA,
                                  { FL_GPIO_PIN_9, FL_GPIO_MODE_DIGITAL, FL_GPIO_OUTPUT_PUSHPULL,
                                    FL_DISABLE, FL_ENABLE, FL_DISABLE } },
};

/**
 * @brief 初始化LPTIM32
 *
 */
void Driver_LPTIM32_Init(void)
{
    FL_LPTIM32_InitTypeDef    timInit;
    FL_LPTIM32_OC_InitTypeDef timOCInit;

    /*---------------- 定时器时间基准配置 ----------------*/
    FL_LPTIM32_StructInit(&timInit);

    timInit.clockSource          = FL_CMU_LPTIM32_CLK_SOURCE_APBCLK;
    timInit.mode                 = FL_LPTIM32_OPERATION_MODE_NORMAL;
    timInit.prescalerClockSource = FL_LPTIM32_CLK_SOURCE_INTERNAL;
    timInit.prescaler            = FL_LPTIM32_PSC_DIV32;
    timInit.autoReload           = 100 - 1;
    timInit.onePulseMode         = FL_LPTIM32_ONE_PULSE_MODE_CONTINUOUS;
    timInit.triggerEdge          = FL_LPTIM32_ETR_TRIGGER_EDGE_RISING;
    timInit.countEdge            = FL_LPTIM32_ETR_COUNT_EDGE_RISING;
    FL_LPTIM32_Init(LPTIM32, &timInit);

    /*---------------- 输出比较配置 ----------------*/
    for (uint8_t i = 0; i < LPTIM32_GPIO_INDEX_MAX; ++i) {
        FL_GPIO_Init(lptimGPIOConfigList[i].port, &(lptimGPIOConfigList[i].gpioInit));
    }

    timOCInit.OCPolarity   = FL_LPTIM32_OC_POLARITY_INVERT;
    timOCInit.compareValue = 0;
    FL_LPTIM32_OC_Init(LPTIM32, FL_LPTIM32_CHANNEL_1, &timOCInit);
    FL_LPTIM32_OC_Init(LPTIM32, FL_LPTIM32_CHANNEL_2, &timOCInit);
    /*---------------------------------------------*/

    /* 使能LPTIM32 */
    FL_LPTIM32_Enable(LPTIM32);

    Driver_LPTIM32_SetChannelDutyAndState(LPTIM32, FL_LPTIM32_CHANNEL_1, false, 0, false);
    Driver_LPTIM32_SetChannelDutyAndState(LPTIM32, FL_LPTIM32_CHANNEL_2, false, 0, false);
}

/**
 * @brief 按照设定的占空比 使能或禁用 选择的通道
 *
 * @param gptimX            定时器号
 * @param channel           通道号
 * @param isComplementary   是否为互补通道
 * @param dutyCycle         占空比
 * @param isEnable          使能 or 禁用
 */
void Driver_LPTIM32_SetChannelDutyAndState(void *lptim32, uint32_t channel, bool isComplementary,
                                           uint8_t dutyCycle, bool isEnable)
{
    Driver_LPTIM32_SetDutyCycle(channel, dutyCycle);

    if (channel > FL_LPTIM32_CHANNEL_4) {
        LOG("Driver_LPTIM32_SetChannelDutyAndState(): channel error!\n");
        return;
    }

    if (isEnable) {
        FL_LPTIM32_SetChannelMode(LPTIM32, FL_LPTIM32_CHANNEL_MODE_OUTPUT, channel);
    }
    else {
        FL_LPTIM32_SetChannelMode(LPTIM32, FL_LPTIM32_CHANNEL_MODE_DISABLE, channel);
    }
}

/**
 * @brief 设置占空比
 *
 * @param channel       通道号
 * @param dutyCycle     占空比
 */
static void Driver_LPTIM32_SetDutyCycle(uint32_t channel, uint8_t dutyCycle)
{
    if (dutyCycle > FULL_DUTY_CYCLE) {
        dutyCycle = FULL_DUTY_CYCLE / 2;
    }

    switch (channel) {
    case FL_LPTIM32_CHANNEL_1: FL_LPTIM32_WriteCompareCH1(LPTIM32, dutyCycle); break;
    case FL_LPTIM32_CHANNEL_2: FL_LPTIM32_WriteCompareCH2(LPTIM32, dutyCycle); break;
    case FL_LPTIM32_CHANNEL_3: FL_LPTIM32_WriteCompareCH3(LPTIM32, dutyCycle); break;
    case FL_LPTIM32_CHANNEL_4: FL_LPTIM32_WriteCompareCH4(LPTIM32, dutyCycle); break;
    default:                   LOG("Driver_LPTIM32_SetDutyCycle(): channel error!\n"); break;
    }
}
